package com.jeejam.classLoader;

import org.apache.catalina.Container;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.loader.WebappLoader;

import java.io.*;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

/**
 * 从War中的MANIFEST.MF获得类路径并进行额外加载
 */
public class ManifestClasspathWebappLoader extends WebappLoader {

    public ManifestClasspathWebappLoader() {
        super();
    }


    public ManifestClasspathWebappLoader(ClassLoader parent) {
        super(parent);
    }

    @Override
    protected void startInternal() throws LifecycleException {
        final Container container = getContainer();
        if (container instanceof StandardContext) {

//            StandardContext standardContext = new StandardContext();
//            standardContext.getRealPath();

            File baseFile = new File(((StandardContext) container).getRealPath(""));

            if (baseFile.exists() && baseFile.canRead()) {  //是否可读

                if (baseFile.isDirectory()) {     //目录

                    final File manifestFile = new File(baseFile, "META-INF/MANIFEST.MF");

                    if (manifestFile.exists() && manifestFile.canRead() && manifestFile.isFile()) {     //MANIFEST.MF文件可读

                        System.out.println("[DIST] found MANIFEST.MF" + manifestFile);

                        try {
                            FileInputStream fileInputStream = new FileInputStream(manifestFile);
                            setClasspaths(baseFile, fileInputStream);

                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }

                    }

                } else if (baseFile.isFile()) { //文件（war）

                }

            }
        }

        super.startInternal();
    }

    /**
     * 设置MANIFEST.MF流中的类路径
     *
     * @param baseFile
     * @param inputStream
     */
    private void setClasspaths(File baseFile, InputStream inputStream) {
        String classpaths[] = null;
        try {
            final Manifest manifest = new Manifest(inputStream);
            final Attributes attributes = manifest.getMainAttributes();
            String classpathValue = attributes.getValue("Class-Path");
            if (classpathValue != null) {          //可以不为null说明发现Class-Path
                classpathValue = classpathValue.replaceAll("[\r\n]+$", ""); //移除换行
                classpaths = classpathValue.split("\\s+");     //拆分类路径字符串
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (classpaths != null) {   //如果发现类路径则设置类路径
            for (String classpath : classpaths) {
                addRepository(new File(baseFile.getParent(), classpath).toURI().toString());    //转换相对路径为实际路径并转换为URI
            }
            System.out.println("[DIST] " + baseFile.getName() + " append " + classpaths.length + " classpaths.");

        }

    }

}


